home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-08-18 | 62.7 KB | 1,337 lines |
- FAQPAS.TXT Frequently (and not so frequently) asked Turbo Pascal
- questions with Timo's answers. The questions are in no particular
- order.
- Comments and corrections are solicited.
-
- ..................................................................
- Prof. Timo Salmi Co-moderator of comp.archives.msdos.announce
- Moderating at garbo.uwasa.fi anonymous FTP archives 128.214.87.1
- Faculty of Accounting & Industrial Management; University of Vaasa
- Internet: ts@uwasa.fi Bitnet: salmi@finfun; FI-65101, Finland
-
- -------------------------------------------------------------------
- 1) How do I disable or capture the break key in Turbo Pascal?
- 2) How do I get a printed documentation of my students' TP runs?
- 3) What is the code for the weekday of a given date?
- 4) Need a program to format Turbo Pascal source code consistently
- 5) Can someone give me advice for writing a tsr program?
- 6) Why can't I read / write the com ports?
- 7) What are interrupts and how to use them in Turbo Pascal?
- 8) Should I upgrade my Turbo Pascal version?
- 9) How do I execute an MsDos command from within a TP program?
- 10) How is millisecond timing done?
- 11) How can I customize the text characters to my own liking?
- 12) How to find the files in a directory and subdirectories?
- 13) I need a power function but there is none in Turbo Pascal.
- 14) How can I create arrays that are larger than 64 kilobytes?
- 15) How can I test that the printer is ready?
- 16) How can I clear the keyboard type-ahead buffer.
- 17) How can I utilize expanded memory (EMS) in my programs?
- 18) How can I obtain the entire command line?
- 19) How do I redirect text from printer to file in my TP program?
- 20) Turbo Pascal is for wimps. Use standard Pascal or C instead?
- 21) How do I turn the cursor off?
- 22) How to find all roots of a polynomial?
- 23) What is all this talk about "Pascal homework on the net"?
- 24) How can I link graphics drivers directly into my executable?
- 25) How can I trap a runtime error?
- 26) How to get ansi control codes working in Turbo Pascal writes?
- 27) How to evaluate a function given as a string to the program?
- 28) How does one detect whether input (or output) is redirected?
- 29) How does one set the 43/50 line text mode?
- 30) How can I assign a value to an environment variable in TP?
- -------------------------------------------------------------------
-
- Unless otherwise stated the answers cover versions 4.0, 5.0, 5.5,
- 6.0 and 7.0 (real mode). The Q&As are not for Turbo Pascal version 3
- or earlier. Objects, TVision, or Windows are not covered. (I do not
- use them myself.)
-
- From ts@uwasa.fi Wed Aug 18 00:00:01 1993
- Subject: Disabling or capturing the break key
-
- 1. *****
- Q: I don't want the Break key to be able to interrupt my TP
- programs. How is this done?
- Q2: I want to be able to capture the Break key in my TP program.
- How is this done?
- Q3: How do I detect if a certain key has been pressed?
-
- A: This very frequently asked question is basically a case of RTFM
- (read the f*ing manual). But this feature is, admittedly, not very
- prominently displayed in the Turbo Pascal reference. (As a general
- rule we should not use the newsgroups as a replacement for our
- possibly missing manuals, but enough of this line.)
- There is a CheckBreak variable in the Crt unit, which is true by
- default. To turn if off use
- uses Crt;
- :
- CheckBreak := false;
- :
- Besides turning off break checking this enables you to capture the
- pressing of the break key as you would capture pressing ctrl-c. In
- other words you can use e.g.
- :
- procedure TEST;
- var key : char;
- begin
- repeat
- if KeyPressed then
- begin
- key := ReadKey;
- case key of
- #3 : begin writeln ('Break'); exit; end; {ctrl-c or break}
- else write (ord(key), ' ');
- end; {case}
- end; {if}
- until false;
- end; (* test *)
- :
- IMPORTANT: Don't test the ctrl-break feature just from within the TP
- IDE, because it has ctlr-break handler ("intercepter") of its own
- and may confuse you into thinking that ctrl-break cannot be
- circumvented by the method given above.
- The above example has a double purpose. It also shows the
- rudiments how you can detect if a certain key has been pressed. This
- enables you to give input without echoing it to the screen, which is
- a later FAQ in this collection.
- This is, however, not all there can be to break checking, since
- the capturing is possible only at input time. It is also possible to
- write a break handler to interrupt a TP program at any time. For
- more details see Ohlsen & Stoker, Turbo Pascal Advanced Techniques,
- Chapter 7.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:02 1993
- Subject: Directing output also to printer
-
- 2. *****
- Q: I want to have a printed documentation of my students' Turbo
- Pascal program exercises. How is all input and output directed also
- to the printer?
-
- A1: Use a screen capturing program to put everything that comes
- onto the screen into a file, and print the file. See FAQPROGS.TXT in
- /pc/ts/tsfaqn37.zip (or whatever version number is the current) for
- more about these programs. Available by anonymous FTP or mail server
- from garbo.uwasa.fi.
-
- A2: See the code in TSPAS.NWS (item: Redirecting writes to the
- printer) in the /pc/ts/tspa33??.zip (or whatever is the current
- version number) Turbo Pascal units package (?? = 40, 50, 55, 60, or
- 70 depending on your TP version). Alternatively use USECON and
- USEPRN routines in the TSUNTG unit of the same package.
-
- +------------------------------------------+
- ! To get these and other packages given as !
- ! /dir/subdir/name !
- ! see the instructions in PD2ANS.TXT !
- +------------------------------------------+
-
- A3: But the really elegant solution to the problem of getting a
- logfile (or a printed list) of a Turbo Pascal run is to rewrite the
- write(ln) and read(ln) device driver functions. In itself writing
- such driver redirections is very advanced Turbo Pascal programming,
- but when the programming has once been done, the system is extremely
- easy to use as many times as you like. It goes like this. The driver
- redirections are programmed into a unit (say, tpulog or tpuprn). All
- that is needed after that is to include the following uses statement
- into the program (the target program) which has to be logged:
- uses TPULOG; ( or ) uses TPUPRN;
- This is all there is to it. Just adding one simple line to the
- target program. (If you call any other units, "uses tpulog" must
- come AFTER the system units (eg Dos), but BEFORE any which you may
- define yourself!)
- The reason that I have named two units here instead of just one
- in the above example is that the preferred log for the target
- program may be a logfile or the printer. The better solution of
- these two is to use the logfile option, and then print it. The
- reason is simple. If the target program itself prints something,
- your printout will look confused.
- The logging also has obvious limitations. It works for standard
- input and output (read(ln) and write(ln)) only. 1) It does not
- support graphics, in other words it is for the textmode. 2) It does
- not support direct (Crt) screen writes. 3) And, naturally it only
- shows the input and output that comes to the screen. Not any other
- input or output, such as from or to a file. 4) Furthermore, you are
- not allowed to reassign input or output. Statements like assign
- (output, '') will result in a crash, because the rewritten output
- device redirections are invalidated by such statements. 5) The
- device on the default drive must not be write protected, since else
- the logfile cannot be written to it. 6) It does not work for Turbo
- Pascal 4.0. Despite these restrictions, the method is perfectly
- suited for logging students' Turbo Pascal escapades.
- It is advisable first to test and run your target program without
- "tpulog", so that if you get any strange errors you'll know whether
- they are caused by the logging.
- Where to get such a unit. The code can be found in Michael
- Tischer (1990), Turbo Pascal Internals, Abacus, Section 4.2. Next a
- few of my own tips on this unit Tischer calls Prot. 1) The code is
- in incorrect order. The code that is listed on pages 142 - 145 goes
- between pages 139 and 140. 2) You can change the logfile name (const
- prot_name) to lpt1 for a printed list of the target program run. In
- that case it is advisable to include a test for the online status of
- the printer within Tischer's unit. 3) I see no reason why the two
- lines in Tischer's interface section couldn't be transferred to the
- implementation section. Why have any global definitions? But all in
- all, it works like magic!
-
- A4: From: abcscnuk@csunb.csun.edu (Naoto Kimura (ACM))
- Subject: Re: Printing a log of students' exercises revisited
- To: ts@uwasa.fi
- Date: Fri, 2 Nov 90 20:52:03 pdt
- [Reproduced with Naoto's kind permission]
- By the way, several months ago, I had submitted a file (nktools.zip)
- file on Simtel20 that contains sources to a unit (LOGGER), which
- allows logging of I/O going through the standard input and output
- files, while still being able to use the program interactively. I
- believe that I also submitted a copy to your site. It was something
- I put together for use by students here at California State
- University at Northridge. The source works equally well in all
- presently available versions of Turbo Pascal.
- The only requirements are that
- * you place it as one of the last entries in the USES clause. If
- there is anything that redirects the standard input and output
- file variables, you should put that unit before my unit in the
- USES clause, so that it can see the I/O stream.
- * Don't use the GotoXY and similar screen display control
- procedures in the Crt unit and expect it to come out the same way
- you had it on the display. Since all my unit does is just
- capture the I/O stream to send it through the normal channels and
- also to the log file, all screen control information is not sent
- to the log file.
- * All I/O you want logged should go through the standard input and
- output file variables.
- * Don't close the standard input and output file variables, because
- it will cause problems. Basically, as far as I have checked, it
- just causes the logging to stop at that point.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:03 1993
- Subject: Code to give the weekday of a date
-
- 3. *****
- Q: I want code that gives the weekday of the given date.
-
- A1: There is a WKDAYFN function in /pc/ts/tspa33*.zip (or whatever
- version number is the latest, and where * is 40 50 55 60 and 70)
- Turbo Pascal units collection to give the modern weekday based on
- Zeller's congruence. Available by anonymous FTP or mail server from
- garbo.uwasa.fi. Also you can find a more extensive Julian and
- Gregorian weekday algorithm with source code in Dr.Dobb's Journal,
- June 1989, p. 148. Furthermore Press & Flannery & al (1986),
- Numerical Recipes, Cambridge University Press, present a weekday
- code. The Numerical Recipes codes are available as
- /pc/turbopas/nrpas13.zip (big, 404k!).
-
- A2: Some will recommend the following kludge. Store the current
- date, change it, and let MsDos get you the weekday. Don't use it! It
- is a bad suggestion. On top of being sloppy programming, there are
- several snags. The trick works only for years 1980-2079. A crash
- the program may leave the clock at a wrong date. And even if
- multitasking is rare, in a multitasking environment havoc may result
- for the other tasks. And you may have a TSR that requires the
- correct date, etc.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:04 1993
- Subject: Pretty printers (or uniform code)
-
- 4. *****
- Q: Where can I find a program that formats my (or my students')
- Turbo Pascal code in a consistent matter.
-
- A: What you are asking for is often called "a pretty printer".
- TurboPower Software's (the usual disclaimer applies) commercial
- Turbo Analyst has a facility for this with many options. There are
- also PD and shareware pretty printers, such as /pc/turbopas/
- pritprn.zip, bp7sb*.zip "Source Beautifier for Borland Pascal by
- J.Ferincz", and others at garbo.uwasa.fi available by anonymous FTP
- or mail server. See /pc/INDEX.ZIP for a list of the files.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:05 1993
- Subject: How to write TSR programs
-
- 5. *****
- Q: Can someone give me advice for writing a tsr program.
-
- A: Writing a terminate and stay resident program can be considered
- advanced programming and is beyond the scope of an electronic
- message with limited space. Instead, here are some references to
- Turbo Pascal books and papers which have a coverage of the subject.
- Stephen O'Brien, Turbo Pascal, The Complete Reference, Chapter 16;
- Stephen O'Brien, Turbo Pascal, Advanced Programmer's Guide, Chapter
- 6; Michael Tischer, Turbo Pascal Internals, Chapter 11 (a definite
- bible of TP programming!); Michael Yester, Using Turbo Pascal,
- Chapter 19; Kent Pottebaum, "Creating TSR Programs with Turbo
- Pascal", Dr. Dobb's Journal, May 1989 and June 1989; Kris Jamsa, Dos
- Power User's Guide, pp. 649-.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:06 1993
- Subject: Programming com ports
-
- 6. *****
- Q: Why can't I read / write the com ports.
-
- A: Com port programming (most often writing telecommunication
- programs) is much much more complicated than simply trying to use
- write (com, whatever);
- read (com, whatever);
- This is a very advanced subject (frankly, beyond me), and the best
- way to learn is to try to obtain some code to show you how. One
- place to look at is Turbo Pascal text-books (I have a long list of
- them at garbo.uwasa.fi archives in /pc/ts/tsfaqp*.zip. There also is
- an example by David Rind in garbo.uwasa.fi/pc/pd2/faquote.zip.
- Another source is International FidoNet pascal conference at some
- bulletin board near you. The conference has had some very good
- discussions in it. (No, I don't have them stored for distribution,
- nor any further information.)
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:07 1993
- Subject: Primers to interrupt programming
-
- 7. *****
- Q: What are interrupts and how to use them in Turbo Pascal?
-
- A: An interrupt is a signal to the processor from a program, a
- hardware device, or the processor itself, to suspend temporarily
- what the program is doing, and to perform a routine that is stored
- in the operating system. There are 256 such interrupt routines, with
- many subservices stored in memory at locations, which are given in
- the so called interrupt table. Turbo Pascal (somewhat like C) has a
- special keyword Intr, and a predefined variable registers (in the
- Dos unit) to access these interrupt routines. One way of looking at
- them is as Turbo Pascal (complicated lowlevel) subroutines that are
- already there ready for you to call.
- A detailed description of interrupt routines is way beyond a
- single message with limited space. Instead, I shall give a simple
- example, and good references to the subject. (For a somewhat more
- comprehensive description of what an interrupt is, see INTERRUP.PRI
- in Ralf Brown's garbo.uwasa.fi:/pc/programming/inter35b.zip.)
- :
- uses Dos;
- (* This procedure turns on the border color for CGA and VGA *)
- procedure BORDER (color : byte);
- var regs : registers; (* Predeclared in the Dos unit *)
- begin
- FillChar (regs, SizeOf(regs), 0); (* A precaution *)
- regs.ax := $0B00; (* Service number *)
- regs.bh := $00; (* Subservice number *)
- regs.bl := color;
- Intr ($10, regs); (* ROM BIOS video driver interrupt *)
- end; (* border *)
- If you are new the subject and / or want ideas on the most useful
- interrupts in Turbo Pascal programming, Ben Ezzel (1989),
- Programming the IBM User Interface Using Turbo Pascal, is definitely
- the best reference to look at. There are also many other good
- references for a novice interrupt user, such as Jamsa & Nameroff,
- Turbo Pascal Programmer's Library.
- If you are a more advanced interrupt user you'll find the
- following references very useful. Michael Tischer (1990), Turbo
- Pascal Internals; Norton & Wilton (1988), The New Peter Norton
- Programmer's guide to the IBM PC & PS/2; Ray Duncan (1988), Advanced
- MS-DOS Programming; Terry Dettmann (1989), Dos Programmer's
- Reference, Second edition, Que. Furthermore, there is an impressive
- list of interrupts collected and maintained by Ralf Brown. His
- extensive /pc/programming/inter35a.zip, inter35b.zip and
- inter35c.zip (or whatever are the current versions when you read
- this) is available by anonymous FTP or mail server from
- garbo.uwasa.fi. A definite must for an advanced user. Also see the
- reference to Brown's and Kyle's book in the bibliography at the end
- of this FAQ. Another useful (but in many respects a replicate) list
- is contained in the file /pc/programming/dosref22.zip (or, sigh,
- whatever is the current version). There is also a good hypertext
- advanced programmer's quick reference /pc/programming/helppc21.zip
- which you might find useful.
- One more point for Turbo Pascal users. When Borland upgraded from
- version 3 to 4.0 quite a number of tasks that needed to be done
- using interrupts (such as getting the current time) were included as
- normal TP routines. This means that while definitely useful,
- interrupt programming is now relevant only in advanced Turbo Pascal
- programming. Turbo Pascal 5.0 introduced a few more, but you can
- find some of the missing TP 4.0 routines in the compatibility unit
- in my garbo.uwasa.fi:/pc/ts/tspa3340.zip TP units collection.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:08 1993
- Subject: Borland's Turbo Pascal upgrades
-
- 8. *****
- Q: Should I upgrade my Turbo Pascal version?
-
- A1: Depends on what version you are using, and for what purposes.
- If you are using version 3, the answer is a definite yes. There are
- so many useful additions in the later version, including the concept
- of units, and a great number of new useful keywords. The only reason
- that I can think of for using TP 3 is that it makes .com files
- (which reside in one memory segment only) instead of .exe files. As
- an accounting and business finance teacher and researcher I've been
- somewhat surprised to see postings stating that some users still
- have to program in TP 3.0 because their employer doesn't want to
- take the cost of upgrading. I find this cost argument ridiculous.
- How about some consideration for cost effectiveness and
- productivity?
- If you are currently using version 4.0, the most important point
- in considering upgrading is the integrated debugger in the later
- versions. It is really good, and useful if you write much code.
- There are some minor considerations, as well. Later versions contain
- some useful routines which 4.0 does not. I have programmed many of
- them to be available also for 4.0 in my /pc/ts/tspa3340.zip TO units
- collection (or whatever is the latest when you read this).
- Furthermore, I find somewhat annoying that the executables will
- always end up in the default directory.
- If you are currently using version 5.0 the rational reasons for
- upgrading are needing objects, and a better overlay manager. I have
- also version 5.5 myself, but switched back to version 5.0 after I
- had some problems with its linking of object files. (This is a false
- statement from me, since it turned out that I had made a mistake
- myself. My thanks are due to bj_stedm@gould2.bristol-poly.ac.uk
- (Bruce Stedman) for questioning this item). Anyway, I don't use nor
- need OOP objects (don't confuse linking object files and object
- oriented programming here). One further point for 5.5. It has a
- better help function than 5.0, and a few more procedures and
- predefined constants. The TP 5.5 help includes examples, which can
- be even pasted into your program. This is handy.
- The real snag in upgrading (waiving the reasonable cost) is the
- fact that the units of the different versions are incompatible. If
- you have a large library of units (as I do) you will have to
- recompile the lot. This is something that has caused a fair amount
- of justifiable flak against an otherwise excellent product.
- A tip. Don't throw away your Turbo Pascal version 3.0 manual, if
- you have one. It is of use if you resort to the Turbo3 and Graph3
- compatibility units. They give you access e.g. to turtle graphics.
- At the time of first writing this Turbo Pascal 6.0 version had
- just been announced. I didn't have it yet myself, but I had been
- (correctly) informed that its units are not compatible with the
- earlier versions. I now have Turbo Pascal 6.0, and I must say that
- my reactions have been disappointment and frustration. This is
- probably partly (but not entirely) my own fault, since Turbo Pascal
- seems to be headed from a common programming language into a full
- professional's specialized tool, with many features I don't know how
- to utilize. The only advancement from my point of view really is the
- multiple file editing, but I have long had alternative programs for
- that. If I used assembler (I don't) I am sure that I would find
- useful TP 6.0's potential to include assembler code as such instead
- of having to use the cumbersome Inline procedure of entering the
- assembler code.
- There is also a Windows Turbo Pascal, as the latest addition to
- the plethora. Since I don't use Windows at all, I have no futher
- information on it.
- I think a pattern is emerging here. Rather than being different
- versions of the same product, the consecutive Turbo Pascals are
- really different products for different purposes. Version 3.0 was a
- simple programming language. Version 4.0 extended it into a full
- scale programming modular platform. Version 5.0 introduced the
- debugger. And there an advanced hobbyist's path ended. Version 5.5
- introduced object oriented programming, which I'm sure is important
- for the initiated, but personally I just don't need it even if I
- write a lot of programs. And with the 6.0 we go completely out of
- the realm of conventional programming into Turbo Pascal visions.
- And Windows Turbo Pascal is for a different platform, altogether.
- I find the new integrated user interface of TP 6.0 awkward in
- comparison to what was used in the 4.0, 5.0, and 5.5 versions. The
- IDE of TP leaves less free memory than the previous versions.
- Furthermore TP 6.0 IDE performs frequent disk accesses which cause
- slowdowns making it virtually unusable from a floppy. And I
- wonder why Borland didn't at once go all the way to Windows, because
- that is what 6.0 really is. An intermediate, incomplete step in that
- direction. This means that we have a 5th upgrade in line with
- incompatible units. This is aggravating even for a TP fan, isn't it?
- For information on Turbo Pascal version 7.0 and Borland email
- contact numbers see garbo.uwasa.fi:/pc/turbopas/bp7-info.zip. Also
- see bp7bugs*.zip by Duncan Murdoch. Turbo Pascal 7.0 or more
- extensively Borland Pascal 7.0 is a full professional's tool, and
- far beyond for example my moderate programming needs. To list only a
- few of the features are protected mode programming, handling of
- lagre programs, very fast compiling, and a daunting amount of
- matrial elboving away on one's disk space if one ever has the
- patience to look through it all. I would use the word
- "overwhelming". But for a serious programmer this is an impressive
- and a very worthwhile tool. One should not be misled skipping it
- because of my comments which were written from a hobbyist's point of
- view. As a general trend in programs, the well-known columnist John
- C. Dvorak calls this increasing product complexity trend "featurism"
- in PC Computing, May 1993.
-
- A2: From: dmurdoch@watstat.waterloo.edu (Duncan Murdoch),
- Newsgroups: comp.lang.pascal. Included with Duncan's kind
- permission. (Duncan is one of the most knowledgeable and useful
- contributors to the comp.lang.pascal UseNet newsgroup).
- One other reason: there's a bug in the code generator for 4.0
- and 5.0 that makes it handle the Extended (10 byte) real type
- poorly. The code generated makes very poor use of the 8 element
- internal stack on the coprocessor, so that expressions with lots of
- operands like
- e1+e2+e3+e4+e5+e6+e7+e8+e9
- always fail, if all the e's are of type extended. (The generated
- code pushes each operand onto the stack, then does all the adds.
- It's smarter to push and add them one at a time.)
- This makes it a real pain translating numerical routines from
- Fortran, especially since constants are taken to be of type
- extended.
- The bug was fixed in 5.5.
-
- A3: From: Bengt Oehman (d92bo@efd.lth.se): A difference between
- v4.0 and v5.5 is that you can calculate constants in tp55, but not
- in 4.0. I see this as a big advantage. For example:
- CONST MaxW = 10;
- MaxH = 20;
- MaxSize = MaxW*MaxH;
- { or }
- MaxX = 100;
- HalfMaxX = MaxX DIV 2;
- cannot be compiled with 4.0.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:09 1993
- Subject: Shelling from a TP program
-
- 9. *****
- Q: How do I execute an MsDos command from within a TP program?
-
- A: The best way to answer this question is to give an example.
- {$M 2048, 0, 0} (* <-- Important *)
- program outside;
- uses dos;
- begin
- write ('Directory call from within TP by Timo Salmi');
- SwapVectors;
- Exec (GetEnv('comspec'), '/c dir *.*'); (* Execution *)
- SwapVectors;
- (* Testing for errors is recommended *)
- if DosError <> 0 then
- writeln ('Dos error number ', DosError)
- else
- writeln ('Mission accomplished, exit code ', DosExitCode);
- (* For DosError and DosExitCode details see the TP manual *)
- end.
- Alternatively, take a look at execdemo.pas from demos.arc which
- is on the accompanying Turbo Pascal disk.
- What the above Exec does is that it executes the command
- processor. The /c specifies that the command interpreter is to
- perform the command, and then stop (not halt).
- I have also seen it asked how one can swap the Turbo Pascal
- program to the disk when shelling. It is unnecessary to program that
- separately because there is an excellent program to do that for you.
- It is garbo.uwasa.fi:/pc/sysutil/shroom2d.zip.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:10 1993
- Subject: Millisocond timing
-
- 10. *****
- Q: How is millisecond timing done?
-
- A: A difficult task, but the facilities are readily available.
- TurboPower Software's commercial Turbo Professional (don't confuse
- with Borland's Turbo Professional) has a unit for this. (The usual
- disclaimer applies). This one has been released to the PD. It is
- called tptimer and is part of the /pc/turbopas/bonus507.zip package.
- I have also seen a SIMTEL20 upload announcement of a ztimer11.zip
- for C and ASM, but I have no further information on that. Another
- option is /pc/turbopas/qwktimer.zip. It is not quite as accurate as
- tptimer.
- To test the tptimer unit in bonus507.zip you can use the
- following example code
- uses Crt, tptimer;
- var time1, time2 : longint;
- begin
- InitializeTimer;
- time1 := ReadTimer;
- Delay (1356); (* Or whatever code you wish to benchmark *)
- time2 := ReadTimer;
- RestoreTimer;
- writeln ('Elapsed = ', ElapsedTime (time1, time2)/1000.0 : 0 : 3);
- end.
- It is quite another question when you really need the millisecond
- timing. The most common purpose for millisecond timing is testing
- the efficiency of alternative procedures and functions, right? The
- way I compare mine is simple. I call the procedures or functions I
- want to compare for speed, say, a thousand times in a loop. And
- test this for elapsed time. This way the normal resolution (18.2
- cycles per second) of the system clock becomes sufficient. This is
- accurate enough for the comparisons.
- var elapsed : real; i : word;
- elapsed := TIMERFN; (* e.g. from /pc/ts/tspa3355.zip *)
- for i := 1 to 1000 do YOURTEST; (* Try out the alternatives *)
- elapsed := TIMERFN - elapsed;
- writeln ('Elapsed : ', elapsed : 0 : 2);
- Incidentally, if you want to make more elaborate evaluations of the
- efficiency of your code, Borland's Turbo Profiler is a useful tool.
- (The usual disclaimer naturally applies.)
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:11 1993
- Subject: Text font customizing
-
- 11. *****
- Q: How can I customize the text characters to my own liking?
-
- A: As far as I know, text-mode characters are hard-coded, and
- cannot be customized at all unless you have an EGA or VGA adapter.
- But you can always retrieve the bitmap information for the ascii
- characters from your PC.
- The bitmap table for the lower part of the character set (0-127)
- starts at memory position $F000 and ends at $FA6E. The upper part is
- not at a fixed memory location. The pointer to the memory address of
- upper part of the ascii table (provided that graftabl has been
- loaded) is at an address $007C. One way of saying this is that the
- segment address of the upper part's memory location is at $007E, and
- its offset at $007C.
- Going into more details is beyond the scope of this posting. If
- you want more information see Kent Porter (1987), Stretching Turbo
- Pascal, Chapter 12, and Kent Porter & Mike Floyd (1990), Stretching
- Turbo Pascal. Version 5.5. Revised Edition. Brady, Chapter 11.
- If you are interested in a demonstration of utilizing the
- bitmapped character information (no source code available), take a
- look at the demo in the garbo.uwasa.fi anonymous FTP archives file
- /pc/ts/tsdemo15.zip (or whatever version number is current).
- Turbo Pascal also supports what is called stroked fonts (the
- .chr) files which draw characters instead of bitmapping them. The
- user should be able to write one's own .chr definitions, but I have
- no experience nor information on how this can be done.
- There is something called bgikit10.zip which has facilities for
- making fonts and adding graphics drivers. The problem is that I
- cannot make it publicly available, since I think that it is not PD.
- I am still missing the information. Unfortunately, it is not even
- the only case where I encountered the fact that Borland does not
- seem at all interested in the UseNet users' queries about the status
- and distributability of their material.
- (From Leonard Erickson Leonard.Erickson@f51.n105.z1.fidonet.org
- Well, you can *also* do it if you have a Hercules Graphics Card Plus
- or Hercules InColor card (as far as I know, the only cards that
- implemented Hercules RamFont 'standard'). And you can modify the
- upper 128 characters on a CGA card. BTW, the RamFont cards are
- *nice* pity it appeared too late to become a standard. It's a *lot*
- more flexible than EGA/VGA fonts (I can have several *dozen* fonts
- resident).)
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:12 1993
- Subject: Finding files in TP
-
- 12. *****
- Q: How to find the files in a directory AND subdirectories?
-
- A: Writing a program that goes through the files of the directory,
- and all the subdirectories below it, is based on Turbo Pascal's file
- finding commands and recursion. This is universal whether you are
- writing, for example, a directory listing program, or a program that
- deletes, say, all the .bak files, or some other similar task.
- To find (for listing or other purposes) the files in a directory
- you need above all the FindFirst and FindNext keywords, and testing
- the predefined file attributes. You make these a procedure, and call
- it recursively. If you want good examples with source code, please
- see PC World, April 1989, p. 154; Kent Porter & Mike Floyd (1990),
- Stretching Turbo Pascal. Version 5.5. Revised Edition. Brady,
- Chapter 23; and Michael Yester (1989), Using Turbo Pascal, p. 437;
- dirtree.pas in /pc/pcmag/vol8n01.zip.
- The simple (non-recursive) example listing all the read-only
- files in the current directory shows the rudiments of the principle
- of Using FindFirst, FindNext, and the file attributes, because some
- users find it hard to use these keywords.
- uses Dos;
- var FileInfo : SearchRec;
- begin
- FindFirst ('*.*', AnyFile, FileInfo);
- while DosError = 0 do
- begin
- if (FileInfo.Attr and ReadOnly) > 0 then
- writeln (FileInfo.Name);
- FindNext (FileInfo);
- end;
- end. (* test *)
-
- A2: While we are on the subject related to FindFirst and FindNext,
- here are two useful examples:
-
- (* Number of files in a directory (not counting directories) *)
- function DFILESFN (dirName : string) : word;
- var nberOfFiles : word;
- FileInfo : searchRec;
- begin
- if dirName[Length(dirName)] <> '\' then dirName := dirName + '\';
- dirName := dirName + '*.*';
- {}
- nberOfFiles := 0;
- FindFirst (dirName, AnyFile, FileInfo);
- while DosError = 0 do
- begin
- if ((FileInfo.Attr and VolumeId) = 0) then
- if (FileInfo.Attr and Directory) = 0 then
- Inc (nberOfFiles);
- FindNext (FileInfo);
- end; {while}
- dfilesfn := nberOfFiles;
- end; (* dfilesfn *)
-
- (* Number of immediate subdirectories in a directory *)
- function DDIRSFN (dirName : string) : word;
- var nberOfDirs : word;
- FileInfo : searchRec;
- begin
- if dirName[Length(dirName)] <> '\' then dirName := dirName + '\';
- dirName := dirName + '*.*';
- {}
- nberOfDirs:= 0;
- FindFirst (dirName, AnyFile, FileInfo);
- while DosError = 0 do
- begin
- if ((FileInfo.Attr and VolumeId) = 0) then
- if (FileInfo.Attr and Directory) > 0 then
- if (FileInfo.Name <> '.') and (FileInfo.Name <> '..') then
- Inc (nberOfDirs);
- FindNext (FileInfo);
- end; {while}
- ddirsfn := nberOfDirs;
- end; (* ddirsfn *)
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:13 1993
- Subject: A generic power function code for TP
-
- 13. *****
- Q: I need a power function but there is none in Turbo Pascal.
-
- A: Pascals do not have an inbuilt power function. You have to write
- one yourself. The common, but non-general method is defining
- function POWERFN (number, exponent : real) : real;
- begin
- powerfn := Exp(exponent*Ln(number));
- end;
- To make it general use:
- (* Generalized power function by Prof. Timo Salmi *)
- function GENPOWFN (number, exponent : real) : real;
- begin
- if (exponent = 0.0) then
- genpowfn := 1.0
- else if number = 0.0 then
- genpowfn := 0.0
- else if abs(exponent*Ln(abs(number))) > 87.498 then
- begin writeln ('Overflow in GENPOWFN expression'); halt; end
- else if number > 0.0 then
- genpowfn := Exp(exponent*Ln(number))
- else if (number < 0.0) and (Frac(exponent) = 0.0) then
- if Odd(Round(exponent)) then
- genpowfn := -GENPOWFN (-number, exponent)
- else
- genpowfn := GENPOWFN (-number, exponent)
- else
- begin writeln ('Invalid GENPOWFN expression'); halt; end;
- end; (* genpowfn *)
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:14 1993
- Subject: Arrays > 64K
-
- 14. *****
- Q: How can I create arrays that are larger than 64 kilobytes?
-
- A: Turbo Pascal does not directly support the so-called huge arrays
- but you can get by this problem with a clever use of pointers as
- presented in Kent Porter, "Handling Huge Arrays", Dr.Dobb's Journal,
- March 1988. In this method you point to an element of a two
- dimensional array using a^[row].col^[column]. The idea involves too
- much code and explanation to be repeated here, so you'll have to see
- the original reference. But I know from my own experience, that the
- code works like magic. (The code is available from garbo.uwasa.fi
- archives as /pc/turbopas/ddj8803.zip). Kent Porter, "Huge Arrays
- Revisited", Dr.Dobb's Journal, October 1988, presents the extension
- of the idea to huge virtual arrays. (Virtual arrays mean arrays that
- utilize disk space).
- Another possibility is using TurboPower Software's (the usual
- disclaimer applies) commercial Turbo Professional (don't confuse
- with Borland's Turbo Professional) package. It has facilities for
- huge arrays, but they involve much more overhead than Kent Porter's
- excellent method.
-
- (* =================================================================
- My code below is based on a UseNet posting in comp.lang.pascal
- by Naji Mouawad nmouawad@watmath.waterloo.edu. Naji's idea was
- for a vector, my adaptation is for a two-dimensional matrix. The
- realization of the idea is simpler than the one presented by Kent
- Porter in Dr.Dobb's Journal, March 1988. (Is something wrong,
- this is experimental.)
- ================================================================= *)
- {}
- const maxm = 150;
- maxn = 250;
- {}
- type BigVectorType = array [1..maxn] of real;
- BigMatrixType = array [1..maxm] of ^BigVectorType;
- {}
- var BigAPtr : BigMatrixType;
- {}
- (* Create the dynamic variables *)
- procedure MAKEBIG;
- var i : word;
- heapNeeded : longint;
- begin
- heapNeeded := maxm * maxn * SizeOf(real) + maxm * 4 + 8196;
- if (MaxAvail <= heapNeeded) then
- begin writeln ('Out of memory'); halt; end;
- for i := 1 to maxm do New (BigAPtr[i]);
- end; (* makebig *)
- {}
- (* Test that it works *)
- procedure TEST;
- var i, j : word;
- begin
- for i := 1 to maxm do
- for j := 1 to maxn do
- BigAPtr[i]^[j] := i * j;
- {}
- writeln (BigAPtr[5]^[7] : 0:0);
- writeln (BigAPtr[maxm]^[maxn] : 0:0);
- end; (* test *)
- {}
- (* The main program *)
- begin
- writeln ('Big arrays test by Prof. Timo Salmi, Vaasa, Finland');
- writeln;
- MAKEBIG;
- TEST;
- end.
- (For a better test of the heap than in MAKEBIG see Swan (1989), pp.
- 462-463.)
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:15 1993
- Subject: Testing printer status
-
- 15. *****
- Q: How can I test that the printer is ready?
-
- A: The usually advocated method in Turbo Pascal is to test the
- status of regs.ah after a call to interrupt 17 Hex (the parallel
- port driver interrupt), service 02:
- regs.dx := PrinterNumber; (* LPT1 = 0 *)
- regs.ah := $02; (* var regs : registers, uses DOS *)
- Intr ($17,regs); (* Interrupt 17 Hex *)
- status := regs.ah (* var status : byte *)
- But this is not a good method since the combinations of the status
- bits which indicate a ready state can vary from printer to printer
- and PC to PC. If you want a list of the status bits, see eg Ray
- Duncan (1988), Advanced MS-DOS Programming, p. 587. For an example
- of a code using interrupt 17 Hex see Douglas Stivison (1986), Turbo
- Pascal Library, pp. 118-120. Also see Michael Yester (1989), Using
- Turbo Pascal, pp. 494-495.
- The more generic alternative is to try to write a #13 to the
- printer having the i/o checking off, that is, while {$I-} is in
- effect, and testing the IOResult. But then you must first alter the
- printer retry times default (and restore it afterwards). Else the
- method can take up to a minute instead of an immediate response.
- Also, you must have set the FileMode for LPT1 appropriately (and
- restore it afterwards). Sounds a bit complicated, but you don't have
- to do all this yourself. There is a boolean function "LPTONLFN Get
- the online status of the first parallel printer" for this purpose in
- my /pc/ts/tspa33??.zip (or whatever version number is the latest)
- Turbo Pascal units collection available by anonymous FTP or mail
- server from garbo.uwasa.fi.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:16 1993
- Subject: Clearing the keyboard buffer
-
- 16. *****
- Q: How can I clear the keyboard type-ahead buffer.
-
- A: Three methods are usually suggested for solving this problem.
- a) The first is to use something like
- uses Crt;
- var dummy : char;
- while KeyPressed do dummy := ReadKey;
- This kludge-type method has the disadvantage of requiring the Crt
- unit. Also, in connection with procedures relying on ReadKey for
- input, it may cause havoc on the programs logic.
- b) The second method accesses directly the circular keyboard buffer
- var head : word absolute $0040:$001A;
- tail : word absolute $0040:$001C;
- procedure FLUSHKB; begin head := tail; end;
- c) The third method is to call interrupt 21Hex (the MsDos interrupt)
- with the ax register set as $0C00. This method has the advantage of
- not being "hard-coded" like the second method, and thus should be
- less prone to incompatibility.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:17 1993
- Subject: Utilizing expanded memory
-
- 17. *****
- Q: How can I utilize expanded memory (EMS) in my programs?
-
- A: I have no experience (yet?) on this subject myself, but I can
- give you a list of references: Michael Tischer (1990), Turbo Pascal
- Internals, Abacus, Chapter 9; Stephen O'Brien (1988), Turbo Pascal,
- Advanced Programmer's Guide, Borland-Osborne, Chapter 4; Chris
- Ohlsen & Gary Stoker (1989), Turbo Pascal Advanced Techniques, Que,
- Chapter 11, and, maybe most importantly, Dorfman & Neuberger, Turbo
- Pascal Memory Management Techniques (with lots of code).
- Furthermore, Turbo Pascal delivery disks (at least 5.0) contain a
- demos.arc archive which includes a ems.pas file.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:18 1993
- Subject: Capturing the entire command line
-
- 18. *****
- Q: How can I obtain the entire command line (spaces and all)?
-
- A: ParamCount and ParamStr are for parsed parts of the command line
- and cannot be used to get the command line exactly as it was. See
- what happens if you try to capture
- "Hello. I'm here"
- you'll end up with a false number of blanks. For obtaining the
- command line unaltered use
- type CommandLineType = string[127];
- var CommandLinePtr : ^CommandLineType;
- begin
- CommandLinePtr := Ptr(PrefixSeg, $80);
- writeln (CommandLinePtr^);
- end;
- A warning. If you want to get this correct (the same goes for TP's
- own ParamStr and ParamCount) apply them early in your program. At
- least they must be used before any disk I/O takes place!
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:19 1993
- Subject: Redirecting from printer to file
-
- 19. *****
- Q: How do I redirect text from printer to file in my TP program?
-
- A: Simple. This is done in Turbo Pascal by using the assign command
- (think what the word 'assign' implies). Here is a simple example of
- the idea.
- uses Printer;
- begin
- assign (lst, 'printer.log');
- rewrite (lst);
- writeln (lst, 'Hello world');
- close (lst);
- end.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:20 1993
- Subject: Turbo Pascal users are just wimps
-
- 20. *****
- Q: Turbo Pascal is for wimps. Why don't you use standard Pascal or
- better still why don't you use C?
-
- A: These kinds of "real-programmers" statements often reflect what
- is called self-over-others attitude, and they are a part of a kind
- of a programming lore or cult. Basically, these attitudes waive the
- simple fact that one should select one's tools according to the task
- at hand, not vice versa. On the other hand one's productivity is
- usually best when being able to use tools which one is familiar and
- comfortable with. (Note however that the real-programmer's lore is
- not really interested in producing results.)
- In very rough terms there are two attitudes to programming
- languages. They can be seen as tools for writing applications, or
- (by surprisingly many) as ends themselves.
- If we first look at standard Pascal (versus Turbo Pascal),
- considering the language primary and its usage secondary is common.
- This results from the history of Pascal, since as we all know it was
- originally meant as a means for teaching programming concepts, not
- at all for writing applications. But because Pascal turned out to be
- useful also for writing applications, it has been extended for some
- operating systems, most notably MsDos (Turbo Pascal) and VAX/VMS
- (VAX Pascal). Both remedy a lot of flaws from the application
- programmer's point of view. Most notably they have a true file I/O
- interface, and enhanced string handling. Turbo Pascal (the more
- generic of these two) clearly draws from the structure and ideas of
- advanced BASICs (and vice versa). While in standard Pascal the
- language is an end by itself, for Turbo Pascal the only relevant
- issue is its usefulness for writing applications.
- One problem that one encounters when moving away from standard
- Pascal is the problem of portability. This is a truly serious
- problem, since most often extensive rewriting is necessary from
- converting say a Turbo Pascal to, say, Unix Pascal. I have taken
- Unix Pascal as the extreme example, since Unix Pascal in almost
- nothing but the standard Pascal having no useful file I/O.
- If one considers C, its best aspect from applications point of
- view is portability, and its strength for system programming. But it
- is not an easy language to learn. Proponents of C also often have
- the tendency discussed above, that is seeing the language as
- primary, and its utilization as secondary. Now why this tendency,
- not only for C, but in general? I've had the opportunity of writing
- programs starting from the late 1960's, and one observation I have
- made, and often propounded the view is that it is not writing code
- that is the really difficult part. What is really difficult it is
- coming up with good and original ideas for programs to write. I see
- applications as primary, and the tools as secondary. As to Turbo
- Pascal, I've written in many languages (including Cobol, Fortran,
- several Basics and Pascals, and command languages) and I like Turbo
- Pascal because it is one of the most convenient and flexible tools
- for writing the kind of applications that I usually write and
- distribute for the Public Domain. That is I use Turbo Pascal because
- I'm comfortable with it in writing applications, and have thus
- gathered a very useful modular libary for it over the years, not
- because of any inherent value attached to Turbo Pascal per se.
-
- A2: Another, a somewhat resembling line is made up by the arguments
- about standards in Pascal which are recycled in comp.lang.pascal
- time after time. Very often they end up with purists vs pragmatists
- arguing about the true or imaginary viles of using GOTOs. I find all
- this somewhat futile, although I understand the academic nature of
- the background. As you'll recall, Pascal was first developed for
- academic teaching programming concepts, not for any practical
- programming. That came later, and the ensuing popularity of Pascal
- in practical applications must have come as a surprise way back
- then. I admit being biased in not symphatizing with Pascal standard
- stalwarts. I am far more interested in getting the job done than in
- defending a barren orthodoxy.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:21 1993
- Subject: Turning off the cursor
-
- 21. *****
- Q: How do I turn the cursor off?
-
- A: The usually advocated trick for turning the cursor off is to
- equate the lower and the upper scan line of the cursor as explained
- eg in Stephen O'Brien (1988), Turbo Pascal, Advanced Programmer's
- Guide.
- uses Dos;
- var regs : registers;
- begin
- regs.ax := $0100; (* Service $01 *)
- regs.cl := $20; (* Top scan line *)
- regs.ch := $20; (* Botton scan line *)
- Intr ($10, regs); (* ROM BIOS video driver interrupt *)
- end;
- To turn the cursor back on this (and many other) sources suggest
- setting regs.ch and regs.cl as 12 and 13 for mono screen, and 6 and
- 7 for others.
- This is not a good solution since it is equipment dependent, and
- may thus produce unexcepted results. Better to store the current
- scan line settings, and turn off the cursor bit. Below is the code
- from my Turbo Pascal units collection /pc/ts/tspa33??.zip (or
- whatever version number is the latest) available by anonymous FTP
- from garbo.uwasa.fi archives. The general idea is that regs.ch bit 5
- toggles the cursor on / off state. Thus to set the cursor off, apply
- regs.ch := regs.ch or $20; (* $20 = 00100000 *)
- and to set it on, apply
- regs.ch := regs.ch and $DF; (* $DF = 11011111 *)
- (* From TSUNTE unit, which also has a CURSON procedure *)
- procedure CURSOFF;
- var regs : registers;
- begin
- FillChar (regs, SizeOf(regs), 0); (* Initialize, a precaution *)
- {... find out the current cursor size (regs.ch, regs.cl) ...}
- regs.ah := $03;
- regs.bh := $00; (* page 1, superfluous because of FillChar *)
- Intr ($10, regs); (* ROM BIOS video driver interrupt *)
- {... turn off the cursor without changing its size ...}
- regs.ah := $01; (* Below are bits 76543210 *)
- regs.ch := regs.ch or $20; (* Turn on bit 5; $20 = 00100000 *)
- Intr ($10, regs);
- end; (* cursoff *)
-
- A2: Another solution that has been suggested is putting the cursor
- outside the screen using the GoToXY procedure. Fair enough, but then
- you need to use the Crt unit, which is not always desirable.
- Besides, how do you write on the screen if the cursor postion is off
- it?
-
- A3: (Not to be taken seriously). Simple, turn off your computer and
- the cursor stops showing :-).
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:22 1993
- Subject: Finding the roots of a polynomial
-
- 22. *****
- Q: How to find all roots of a polynomial?
-
- A: If you need the code, see Turbo Pascal Numerical Toolbox and/or
- Press & Flannery & Teukolsky & Vetterling (1986), Numerical Recipes,
- The Art of Scientific Computing, Cambridge University Press. The
- Numerical Recipes codes are available as /pc/turbopas/nrpas13.zip
- (big, 404k!). If you just need to solve such a task (without code
- available), get /pc/ts/tsnum12.zip (or whatever version number is
- the latest) from garbo.uwasa.fi archives by anonymous FTP or mail
- server.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:23 1993
- Subject: Pascal homework on the net
-
- 23. *****
- Q: What is all this talk about "Pascal homework on the net"?
-
- A: This is one of the subjects that seems to pop up at regular
- intervals, cause some heated exchange for awhile, and then die down
- again leaving some users harboring warranted or unwarranted grudges.
- Some posters to comp.lang.pascal have been very concerned of the
- possibility that the questions posed on the net are related to
- students' homework assignments. I don't have any unequivocal answers
- or a clearcut stand on this question, just some comments.
- The most important task of a newsgroup like comp.lang.pascal is
- the exchange of information between the users. If you think that
- what you are going to post is interesting and useful to the group,
- that should be your topmost criterion.
- If it is really a student that wants his/her work done on the net
- (how do we know anyway?) also consider the following fact. Being
- able to use a newsgroup amounts to having learned at least something
- about using computers, and that is something per se.
- Even if the student may short-sightedly not see it, providing ALL
- the code for a student's homework is detrimental to the student,
- since it is she/he that foregoes understanding what he/she is doing.
- The group should not condone outright cheating. Being (partly) a
- teacher myself, I understand also this view.
- If a student is stuck with a problem in his/her code, I don't see
- any real harm in helping out, especially if the problem has general
- interest. Instructing is what teaching is about, anyway, isn't it?
- But, on the other hand, I must admit that I find a it rather
- flagrant if a posting asks for something of the kind "I have to
- complete my term assignment to write a function plotter by the end
- of this month. Send me the code, since I'm too busy with my other
- exams to write it myself" (a true quote).
- Finally, let's not jump to premature conclusions about anyone's
- questions. That's what most often triggers off a vicious circle of
- flaming.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:24 1993
- Subject: Linking bgi drivers into executables
-
- 24. *****
- Q: How can I link graphics drivers directly into my executable?
-
- A: This is a complicated, yet a very useful task, because then you
- won't need any separate graphics drivers (or fonts) to go separately
- along with your program. Unfortunately, Turbo Pascal documentation
- on this task is a bit confusing.
- 1) The very first step is to get the necessary files from the
- Turbo Pascal disks to your working directory. To start with, you'll
- need binobj.exe and all the .bgi files.
- 2) Run the following commands (best to place them in a batch,
- call it eg makeobj.bat):
- binobj cga.bgi cga CGADriverProc
- binobj egavga.bgi egavga EGAVGADriverProc
- binobj herc.bgi herc HercDriverProc
- binobj pc3270.bgi pc3270 PC3270DriverProc
- binobj att.bgi att ATTDriverProc
- rem binobj ibm8514.bgi 8514 IBM8514DriverProc
- 3) Get drivers.pas from the Turbo Pascal disk and compile it with
- Turbo Pascal. Now you have a drivers.tpu unit which contains all the
- graphics drivers.
- 4) Now you won't need the .bgi and the .obj files any more. You
- may delete them from your working directory.
- 5) Write your graphics program in the usual manner. But before
- putting your program in the graphics mode use the following
- procedure if you want to link e.g. the EGAVGA graphics driver
- directly into your executable. (Link just the driver(s) you'll need,
- since the drivers take up a lot of space.)
- uses Graph, Drivers;
- :
- procedure EGAVGA2EXE;
- begin
- if RegisterBGIdriver(@EGAVGADriverProc) < 0 then
- begin
- writeln ('EGA/VGA: ', GraphErrorMsg(GraphResult));
- halt(1);
- end;
- end; (* egavga2exe *)
- :
- Incidentally, although this is a slightly different matter, you
- can link any data material into your executable. See Stephen
- O'Brien, (1988), Turbo Pascal, Advanced Programmer's Guide, pp. 31 -
- 35 for more details.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:25 1993
- Subject: Trapping runtime errors
-
- 25. *****
- Q: How can I trap a runtime error?
-
- A: What you are probably asking for is a method writing a program
- termination routine of your own. To do this, you have to replace
- Turbo Pascal's ExitProc with your own customized exec procedure.
- Several Turbo Pascal text books show ho to do this. See eg Tom Swan
- (1989), Mastering Turbo Pascal 5.5, Third edition, Hayden Books, pp.
- 440-454; Michael Yester (1989), Using Turbo Pascal, Que, pp.
- 376-382; Stephen O'Brien (1988), Turbo Pascal, Advanced Programmer's
- Guide, pp. 28-30; Tom Rugg & Phil Feldman (1989), Turbo Pascal
- Programmer's Toolkit, Que, pp. 510-515. Here is an example
- var OldExitProcAddress : Pointer;
- x : real;
- {$F+} procedure MyExitProcedure; {$F-}
- begin
- if ErrorAddr <> nil then
- begin
- writeln ('Runtime error number ', ExitCode, ' has occurred');
- writeln ('The error address in decimal is ',
- Seg(ErrorAddr^):5,':',Ofs(ErrorAddr^):5);
- writeln ('That''s all folks, bye bye');
- ErrorAddr := nil;
- ExitCode := 0;
- end;
- {... Restore the pointer to the original exit procedure ...}
- ExitProc := OldExitProcAddress;
- end; (* MyExitProcedure *)
- (* Main *)
- begin
- OldExitProcAddress := ExitProc;
- ExitProc := @MyExitProcedure;
- x := 7.0; writeln (1.0/x);
- x := 0.0; writeln (1.0/x); {The trap}
- x := 7.0; writeln (4.0/x); {We won't get this far}
- end.
- :
- Actually, I utilize this idea in my /pc/ts/tspa33??.zip Turbo Pascal
- units collection, which includes a TSERR.TPU. If you put TSERR in
- your program's uses statement, all the run time errors will be given
- verbally besides the usual, cryptic error number. That's all there
- is to it. That is, the inclusion to the uses statment to your main
- program (if you have the program in several units) is all you have
- to do to enable this handy feature.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:26 1993
- Subject: Using ansi codes in a TP program
-
- 26. *****
- Q: How to get ansi control codes working in Turbo Pascal writes?
-
- A: It is very simple, but one has to be aware of the pitfalls.
- Let's start from the assumption that ansi.sys or a corresponding
- driver has been loaded, and that you know ansi codes. If you don't,
- you'll find that information in the standard MsDos manual. To apply
- ansi codes you just include the ansi codes in your write statements.
- For example the following first clears the screen and then puts the
- text at location 10,10:
- write (#27, '[2J'); (* the ascii code for ESC is 27 *)
- write (#27, '[10;10HUsing ansi codes can be fun');
- If you want to test (as you should) whether ansi.sys or some some
- replacement driver has been loaded, you can use the ISANSIFN
- function from my garbo.uwasa.fi:/pc/ts/tspa33??.zip.
- Now the catches. If you have a
- uses Crt;
- statement in your program, direct screen writes will be used, and
- the ansi codes won't work. You have either to leave out the Crt
- unit, or include
- assign (output, '');
- rewrite (output);
- :
- close (output);
- Occasionally I have seen it suggested that one should just set
- DirectVideo := false;
- This is a popular misconception. It won't produce the desired
- result. I'm not claiming to know the reason for this quirk of Turbo
- Pascal. Rather it is an observation I've made.
-
- -From: Bengt Oehman (d92bo@efd.lth.se)
- The `DirectVideo:=False' statement only tells the Crt unit to use
- BIOS calls instead of using direct video-memory writes. A demo
- program to illustrate the screen writing modes follows:
-
- Program ScreenWriteDemo;
- USES Crt;
- BEGIN
- Writeln('This is written directly to the video memory');
- DirectVideo:=False;
- Writeln('This is written via BIOS interrupt calls (int 10h)');
- Assign(Output,'');
- Append(Output);
- Writeln('This is written via DOS calls (int 21h)');
- END.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:27 1993
- Subject: Writing an expression parser
-
- 27. *****
- Q: How to evaluate a function given as a string to the program?
-
- A: To do this you have to have a routine for parsing and evaluating
- your expression. This is a complicated task requiring a clever use
- of recursion. You can find such code in Stephen O'Brien (1988),
- Turbo Pascal, The Complete Reference. Borland-Osborne/McGraw-Hill,
- Chapter 10. Another, simpler piece of code can be found in Michael
- Yester (1989), Using Turbo Pascal, Que, Chapter 5.
- I've also written such a function evaluation program myself, and
- much of it is based on the ideas in O'Brien with my own corrections
- and enhancements. The resulting program is available as fn.exe
- function evaluator in the /pc/ts/tsfunc13.zip package (or whatever
- version number is the latest). Note however, that the source code is
- not included, nor available.
- Tips from Justin Lee (ossm1jl@rex.uokhsc.edu):
- 9158 Apr 25 1992 garbo.uwasa.fi:/pc/turbopas/parse11.zip
- parse11.zip Recursive expression Turbo Pascal parser from Ron Loewy
- An excellent parser is included with all the Turbo Pascal versions
- since TP4.0 as part of the MCALC or TCALC spreadsheet example
- program. See mcparse.pas or tcparse.pas.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:28 1993
- Subject: Detecting redirection
-
- 28. *****
- Q: How does one detect whether input (or output) is redirected?
-
- A: As we know input to a program can come from a file, from the
- console, or from a pipe or redirection. Examples of the latter are
- type text.dat | program
- program < text.dat
- A Turbo Pascal program can be made to detect the redirections using
- Interrupt 21Hex, function 44Hex, subfunction 00Hex. See PC Magazine
- April 16, 1991, p. 374 for the code, and Duncan (1988), Advanced
- MS-DOS Programming, pp. 412-413 for more information. Alternatively,
- you can utilize the preprogrammed routines
- PIPEDIFN Is the standard input from redirection
- PIPEDNFN Is the standard output redirected to nul
- PIPEDOFN Is the standard output redirected
- from my garbo.uwasa.fi:/pc/ts/ tspa33??.zip units.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:29 1993
- Subject: Setting the 43/50 line text mode
-
- 29. *****
- Q: How does one set the 43/50 line text mode?
-
- A: Quite simple. Just apply TextMode (C80 + font8x8). Requires a
- "uses Crt;". First, however, you should test that you have a at
- least an EGA video adapter. (See DetectGraph in your TP manual).
- Also see TSUTLE.NWS in garbo.uwasa.fi:/pc/ts/tsutle22.zip (or
- whichever version number is the current) for the non-standard wide
- text modes like 132x43.
- --------------------------------------------------------------------
-
- From ts@uwasa.fi Wed Aug 18 00:00:30 1993
- Subject: Assigning environment variable values
-
- 30. *****
- Q: How can I assign a value to an environment variable in TP?
-
- A: For assigning a value to (a parent process's) environment value
- you have to access and manipulate the Program Segment Prefix and
- Memory Control Blocks. This is a rather complicated undertaking. A
- source code with an accompanying article by Trudy Neuhaus can be
- found in PC Magazine Volume 11 Number 1 pages 425-427.
- The budding TP programmers should note that the elementary trick
- of Exec (GetEnv('comspec'), '/c set key=whatever') will achieve only
- a transient result for the duration of the exec shell. When you exit
- the shell after this endeavor, the environment will be as it was.
- Here is about the why. When the above command is executed, MsDos
- makes a copy of the environment, and uses the copy. When the above
- shelling terminates, the copy of the environment is deleted, and the
- original is restored. Hence the above trick cannot be used to change
- the parent environment.
- If you don't want to try to go through this rather complicated
- task yourself, the routines
- "SETENV Set a parent environment variable (variable=value)"
- "SETENVSH Set an environment variable for the duration of shelling"
- can be found in my TP TPU collection garbo.uwasa.fi:/pc/ts/
- tspa33*.zip (* = 40,50,55,60,70). No source code is included, nor
- available, though.
- --------------------------------------------------------------------
-